//
//  BCPerson.m
//  StudyISA
//
//  Created by Shine on 2020/10/28.
//  Copyright © 2020 YW. All rights reserved.
//

#import "BCPerson.h"

// 位掩码：  一般用来做位运算取值赋值的
#define TallMask (1<<0) // 0000 0001 （1）
#define RichMask (1<<1) // 0000 0010  （2）
#define HandsomeMask (1<<2) // 0000 0100 （4）
 
@interface BCPerson()
{
    char _const_person; // 用const_person的低三位来分别表示tall rich handsome的1或者0
    
   // 位域，C语言允许在一个结构体中以位为单位来指定其成员所占内存长度，这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据。
    // 结构体支持 位域
    struct { // 位域
        char tall : 1; //1这这里表示占一位 不是之前系统定义的占一个字节
        char rich : 1;
        char handsome : 1;
    } _tallRichHandsome;
    
    // 联合体
    union {
        // bits是用来使用 struct里是用来解释说明bits里的值分配和作用表示
        char bits; //其实和上面用const_person的方式没什么区别，只是增加了位域的解释说明
        struct{ // 位域 增加可读性 对bits接受说明 而说明的占位加起来不能超过外面的所代表的变量的字节大小
            /*
             这里的tall、rich、handsome顺序没有任何意思，只是解释说明bits有什么占多少位。
             具体的所处的位置主要取决于在set、get的时候与负责哪个区域的掩码进行的位操作运算  一般都是按照从低位到高位的
             */
            char tall : 1;
            char rich : 1;
            char handsome : 1;
        };
    } _unionTallRichHandsome;
       
   /*
    结构体和共用体的区别在于：结构体的各个成员会占用不同的内存，互相之间没有影响；
    而共用体的所有成员占用同一段内存，修改一个成员会影响其余所有成员。
    
    联合体： 内部的变量公用同一个内存地址。这也就意味着当多个变量都进行赋值的时候，可能只有一个变量的地址有正确有效的。
    结构体占用的内存大于等于所有成员占用的内存的总和（成员之间可能会存在缝隙），共用体占用的内存等于最长的成员占用的内存。
    共用体使用了内存覆盖技术，同一时刻只能保存一个成员的值，如果对新的成员赋值，就会把原来成员的值覆盖掉。
    */
}
@end

@implementation BCPerson

- (instancetype)init
{
    self = [super init];
    if (self) {
        _const_person = 0b00000000;
    }
    return self;
}

- (void)setTall:(BOOL)tall{
    
//    if (tall) {
//        _const_person |= TallMask;
//    } else {
//        _const_person &= ~TallMask; //只改变tall的那一位 其他的保持不变
//    }
    
  //  _tallRichHandsome.tall = tall;
    
    if (tall) {
       _unionTallRichHandsome.bits |= TallMask;
    } else {
       _unionTallRichHandsome.bits &= ~TallMask; //只改变tall的那一位 其他的保持不变
    }
    
}
- (void)setRich:(BOOL)rich{
    
//    if (rich) {
//        _const_person |= RichMask;
//    } else {
//        _const_person &= ~RichMask;
//    }
    
    
//    _tallRichHandsome.rich = rich;
    
    if (rich) {
        _unionTallRichHandsome.bits |= RichMask;
    } else {
        _unionTallRichHandsome.bits &= ~RichMask;
    }
}
- (void)setHandsome:(BOOL)handsome{
    
//    if (handsome) {
//        _const_person |= HandsomeMask;
//    } else {
//        _const_person &= ~HandsomeMask;
//    }
    
//    _tallRichHandsome.handsome = handsome;
    
    if (handsome) {
        _unionTallRichHandsome.bits |= HandsomeMask;
    } else {
        _unionTallRichHandsome.bits &= ~HandsomeMask;
    }
}

- (BOOL)isTall{
    
  // return const_person & 1;
  // return _const_person & TallMask;
    
  //  return _tallRichHandsome.tall;
    
   return _unionTallRichHandsome.bits & TallMask;
}
- (BOOL)isRich{
    
  // return const_person & 2;
  // return _const_person & RichMask;
    
//    return _tallRichHandsome.rich;
    
    return _unionTallRichHandsome.bits & RichMask;
}
- (BOOL)isHandsome{
    
  //  return const_person & 4;
  // return _const_person & HandsomeMask;
    
//    return _tallRichHandsome.handsome;
    
    return _unionTallRichHandsome.bits & HandsomeMask;
}




@end
